//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2013 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef _BUOLA_AUTO_FUNCTIONS_H_
#define _BUOLA_AUTO_FUNCTIONS_H_

#include <buola/auto/forward.h>

namespace buola {

///\addtogroup application
///@{

///\name Application life-cycle
//@{

namespace detail {
    //These are internal functions for initialization. They shouldn't be called directly from application code
    void buola_init_start();
    void buola_init_args(int pArgC,char **pArgs);
    void buola_init_app_object(CApp *pApp);
    void buola_init_app_name(const std::string &pName);
    void buola_init_end();
/*namespace detail*/ }

///initializes buola using an application object derived from \ref CApp
///
///It sets signal handlers and runs statically registered init functions.
///
///The provided arguments are used to initialize the default \ref CCmdLine object.
///
///It should be called only once, usually from main(), and the arguments should be the arguments to \c main.
///
///If your program doesn't use an application class derived from \ref CApp, use \ref buola_init instead
///
///\tparam tApp the type of the application. It must be a class derived from \ref CApp
///
///\param pArgC number of arguments the program was called with
///\param pArgs arguments the program was called with
///\param pAppArgs arguments to pass to the constructor of \p tApp
///
///\return the newly created application object
template<typename tApp,typename... tAppArgs>
inline tApp buola_init_app(int pArgC,char **pArgs,tAppArgs &&... pAppArgs)
{
    detail::buola_init_start();
    detail::buola_init_args(pArgC,pArgs);
    tApp *lApp=new tApp(std::forward<tAppArgs>(pAppArgs)...);
    detail::buola_init_app_object(lApp);
    detail::buola_init_end();
    return lApp;
}

///initializes buola
///
///It sets signal handlers and runs statically registered init functions.
///
///The provided arguments are used to initialize \ref CCmdLine.
///
///It should be called only once, usually from main(), and the arguments should be the arguments to \c main.
///
///For programs that use an application class derived from \ref CApp, which is recommended for all
///programs with a GUI, use \ref buola_init_app instead.
///
///\param pArgC number of arguments the program was called with
///\param pArgs arguments the program was called with
///\param pAppName the application name. If it is empty, it defaults to the executable name provided at command line
void buola_init(int pArgC=0,char **pArgs=nullptr,const std::string &pAppName=std::string());

///returns true if buola has been initialized
bool buola_is_init();

///can be called to run the main loop in applications which don't need an instance of CApp
void buola_main_loop();

///returns \c true if a SIGCHLD arrived and it has not been processed yet.
///
///Upon calling this function, the pending sigchld status is reset, so that calling it again before another SIGCHLD
///arrives will always return false.
bool buola_pending_sigchld();

///exits the program with the given return code
///
///Unlike \c ::exit, it doesn't exit the program immediately. Instead, it signals the main event loop
///to return when the current iteration is complete, and sets the future return vale to \p pReturnCode
///
///This return value will later be returned by \ref buola_finish, so that it can be used to return it from
///\c main.
void buola_exit(int pReturnCode=0);

///finishes execution of a buola program
///
///Should always be called at the end of main in a program that uses buola
///\returns the value that should be returned by \c main
int buola_finish();

//@}

///\name Process information
//@{

///returns the pid of the process
int get_pid();

///returns the application name
const std::string &get_application_name();

///returns the host name
const std::string &get_host_name();

///returns a new application-wide uinque ID
uint64_t get_new_uid();

//@}

///@}

/*namespace buola*/ }

#endif
